home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Tcl-Tk 8.0 / Pre-installed version / tk8.0 / generic / tkImage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-15  |  22.6 KB  |  787 lines  |  [TEXT/CWIE]

  1. /* 
  2.  * tkImage.c --
  3.  *
  4.  *    This module implements the image protocol, which allows lots
  5.  *    of different kinds of images to be used in lots of different
  6.  *    widgets.
  7.  *
  8.  * Copyright (c) 1994 The Regents of the University of California.
  9.  * Copyright (c) 1994-1996 Sun Microsystems, Inc.
  10.  *
  11.  * See the file "license.terms" for information on usage and redistribution
  12.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  13.  *
  14.  * SCCS: @(#) tkImage.c 1.14 97/08/11 17:02:02
  15.  */
  16.  
  17. #include "tkInt.h"
  18. #include "tkPort.h"
  19.  
  20. /*
  21.  * Each call to Tk_GetImage returns a pointer to one of the following
  22.  * structures, which is used as a token by clients (widgets) that
  23.  * display images.
  24.  */
  25.  
  26. typedef struct Image {
  27.     Tk_Window tkwin;        /* Window passed to Tk_GetImage (needed to
  28.                  * "re-get" the image later if the manager
  29.                  * changes). */
  30.     Display *display;        /* Display for tkwin.  Needed because when
  31.                  * the image is eventually freed tkwin may
  32.                  * not exist anymore. */
  33.     struct ImageMaster *masterPtr;
  34.                 /* Master for this image (identifiers image
  35.                  * manager, for example). */
  36.     ClientData instanceData;
  37.                 /* One word argument to pass to image manager
  38.                  * when dealing with this image instance. */
  39.     Tk_ImageChangedProc *changeProc;
  40.                 /* Code in widget to call when image changes
  41.                  * in a way that affects redisplay. */
  42.     ClientData widgetClientData;
  43.                 /* Argument to pass to changeProc. */
  44.     struct Image *nextPtr;    /* Next in list of all image instances
  45.                  * associated with the same name. */
  46.  
  47. } Image;
  48.  
  49. /*
  50.  * For each image master there is one of the following structures,
  51.  * which represents a name in the image table and all of the images
  52.  * instantiated from it.  Entries in mainPtr->imageTable point to
  53.  * these structures.
  54.  */
  55.  
  56. typedef struct ImageMaster {
  57.     Tk_ImageType *typePtr;    /* Information about image type.  NULL means
  58.                  * that no image manager owns this image:  the
  59.                  * image was deleted. */
  60.     ClientData masterData;    /* One-word argument to pass to image mgr
  61.                  * when dealing with the master, as opposed
  62.                  * to instances. */
  63.     int width, height;        /* Last known dimensions for image. */
  64.     Tcl_HashTable *tablePtr;    /* Pointer to hash table containing image
  65.                  * (the imageTable field in some TkMainInfo
  66.                  * structure). */
  67.     Tcl_HashEntry *hPtr;    /* Hash entry in mainPtr->imageTable for
  68.                  * this structure (used to delete the hash
  69.                  * entry). */
  70.     Image *instancePtr;        /* Pointer to first in list of instances
  71.                  * derived from this name. */
  72. } ImageMaster;
  73.  
  74. /*
  75.  * The following variable points to the first in a list of all known
  76.  * image types.
  77.  */
  78.  
  79. static Tk_ImageType *imageTypeList = NULL;
  80.  
  81. /*
  82.  * Prototypes for local procedures:
  83.  */
  84.  
  85. static void        DeleteImage _ANSI_ARGS_((ImageMaster *masterPtr));
  86.  
  87. /*
  88.  *----------------------------------------------------------------------
  89.  *
  90.  * Tk_CreateImageType --
  91.  *
  92.  *    This procedure is invoked by an image manager to tell Tk about
  93.  *    a new kind of image and the procedures that manage the new type.
  94.  *    The procedure is typically invoked during Tcl_AppInit.
  95.  *
  96.  * Results:
  97.  *    None.
  98.  *
  99.  * Side effects:
  100.  *    The new image type is entered into a table used in the "image
  101.  *    create" command.
  102.  *
  103.  *----------------------------------------------------------------------
  104.  */
  105.  
  106. void
  107. Tk_CreateImageType(typePtr)
  108.     Tk_ImageType *typePtr;    /* Structure describing the type.  All of
  109.                  * the fields except "nextPtr" must be filled
  110.                  * in by caller.  Must not have been passed
  111.                  * to Tk_CreateImageType previously. */
  112. {
  113.     typePtr->nextPtr = imageTypeList;
  114.     imageTypeList = typePtr;
  115. }
  116.  
  117. /*
  118.  *----------------------------------------------------------------------
  119.  *
  120.  * Tk_ImageCmd --
  121.  *
  122.  *    This procedure is invoked to process the "image" Tcl command.
  123.  *    See the user documentation for details on what it does.
  124.  *
  125.  * Results:
  126.  *    A standard Tcl result.
  127.  *
  128.  * Side effects:
  129.  *    See the user documentation.
  130.  *
  131.  *----------------------------------------------------------------------
  132.  */
  133.  
  134. int
  135. Tk_ImageCmd(clientData, interp, argc, argv)
  136.     ClientData clientData;    /* Main window associated with interpreter. */
  137.     Tcl_Interp *interp;        /* Current interpreter. */
  138.     int argc;            /* Number of arguments. */
  139.     char **argv;        /* Argument strings. */
  140. {
  141.     TkWindow *winPtr = (TkWindow *) clientData;
  142.     int c, i, new, firstOption;
  143.     size_t length;
  144.     Tk_ImageType *typePtr;
  145.     ImageMaster *masterPtr;
  146.     Image *imagePtr;
  147.     Tcl_HashEntry *hPtr;
  148.     Tcl_HashSearch search;
  149.     char idString[30], *name;
  150.     static int id = 0;
  151.  
  152.     if (argc < 2) {
  153.     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  154.         " option ?args?\"", (char *) NULL);
  155.     return TCL_ERROR;
  156.     }
  157.     c = argv[1][0];
  158.     length = strlen(argv[1]);
  159.     if ((c == 'c') && (strncmp(argv[1], "create", length) == 0)) {
  160.     if (argc < 3) {
  161.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  162.             " create type ?name? ?options?\"", (char *) NULL);
  163.         return TCL_ERROR;
  164.     }
  165.     c = argv[2][0];
  166.  
  167.     /*
  168.      * Look up the image type.
  169.      */
  170.  
  171.     for (typePtr = imageTypeList; typePtr != NULL;
  172.         typePtr = typePtr->nextPtr) {
  173.         if ((c == typePtr->name[0])
  174.             && (strcmp(argv[2], typePtr->name) == 0)) {
  175.         break;
  176.         }
  177.     }
  178.     if (typePtr == NULL) {
  179.         Tcl_AppendResult(interp, "image type \"", argv[2],
  180.             "\" doesn't exist", (char *) NULL);
  181.         return TCL_ERROR;
  182.     }
  183.  
  184.     /*
  185.      * Figure out a name to use for the new image.
  186.      */
  187.  
  188.     if ((argc == 3) || (argv[3][0] == '-')) {
  189.         id++;
  190.         sprintf(idString, "image%d", id);
  191.         name = idString;
  192.         firstOption = 3;
  193.     } else {
  194.         name = argv[3];
  195.         firstOption = 4;
  196.     }
  197.  
  198.     /*
  199.      * Create the data structure for the new image.
  200.      */
  201.  
  202.     hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable, name, &new);
  203.     if (new) {
  204.         masterPtr = (ImageMaster *) ckalloc(sizeof(ImageMaster));
  205.         masterPtr->typePtr = NULL;
  206.         masterPtr->masterData = NULL;
  207.         masterPtr->width = masterPtr->height = 1;
  208.         masterPtr->tablePtr = &winPtr->mainPtr->imageTable;
  209.         masterPtr->hPtr = hPtr;
  210.         masterPtr->instancePtr = NULL;
  211.         Tcl_SetHashValue(hPtr, masterPtr);
  212.     } else {
  213.         /*
  214.          * An image already exists by this name.  Disconnect the
  215.          * instances from the master.
  216.          */
  217.  
  218.         masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
  219.         if (masterPtr->typePtr != NULL) {
  220.         for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
  221.             imagePtr = imagePtr->nextPtr) {
  222.            (*masterPtr->typePtr->freeProc)(
  223.                imagePtr->instanceData, imagePtr->display);
  224.            (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0,
  225.             masterPtr->width, masterPtr->height, masterPtr->width,
  226.             masterPtr->height);
  227.         }
  228.         (*masterPtr->typePtr->deleteProc)(masterPtr->masterData);
  229.         masterPtr->typePtr = NULL;
  230.         }
  231.     }
  232.  
  233.     /*
  234.      * Call the image type manager so that it can perform its own
  235.      * initialization, then re-"get" for any existing instances of
  236.      * the image.
  237.      */
  238.  
  239.     if ((*typePtr->createProc)(interp, name, argc-firstOption,
  240.         argv+firstOption, typePtr, (Tk_ImageMaster) masterPtr,
  241.         &masterPtr->masterData) != TCL_OK) {
  242.         DeleteImage(masterPtr);
  243.         return TCL_ERROR;
  244.     }
  245.     masterPtr->typePtr = typePtr;
  246.     for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
  247.         imagePtr = imagePtr->nextPtr) {
  248.        imagePtr->instanceData = (*typePtr->getProc)(
  249.            imagePtr->tkwin, masterPtr->masterData);
  250.     }
  251.     interp->result = Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr);
  252.     } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) {
  253.     for (i = 2; i < argc; i++) {
  254.         hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, argv[i]);
  255.         if (hPtr == NULL) {
  256.         Tcl_AppendResult(interp, "image \"", argv[i],
  257.             "\" doesn't exist", (char *) NULL);
  258.         return TCL_ERROR;
  259.         }
  260.         masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
  261.         DeleteImage(masterPtr);
  262.     }
  263.     } else if ((c == 'h') && (strncmp(argv[1], "height", length) == 0)) {
  264.     if (argc != 3) {
  265.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  266.             " height name\"", (char *) NULL);
  267.         return TCL_ERROR;
  268.     }
  269.     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, argv[2]);
  270.     if (hPtr == NULL) {
  271.         Tcl_AppendResult(interp, "image \"", argv[2],
  272.             "\" doesn't exist", (char *) NULL);
  273.         return TCL_ERROR;
  274.     }
  275.     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
  276.     sprintf(interp->result, "%d", masterPtr->height);
  277.     } else if ((c == 'n') && (strncmp(argv[1], "names", length) == 0)) {
  278.     if (argc != 2) {
  279.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  280.             " names\"", (char *) NULL);
  281.         return TCL_ERROR;
  282.     }
  283.     for (hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
  284.         hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
  285.         Tcl_AppendElement(interp, Tcl_GetHashKey(
  286.             &winPtr->mainPtr->imageTable, hPtr));
  287.     }
  288.     } else if ((c == 't') && (strcmp(argv[1], "type") == 0)) {
  289.     if (argc != 3) {
  290.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  291.             " type name\"", (char *) NULL);
  292.         return TCL_ERROR;
  293.     }
  294.     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, argv[2]);
  295.     if (hPtr == NULL) {
  296.         Tcl_AppendResult(interp, "image \"", argv[2],
  297.             "\" doesn't exist", (char *) NULL);
  298.         return TCL_ERROR;
  299.     }
  300.     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
  301.     if (masterPtr->typePtr != NULL) {
  302.         interp->result = masterPtr->typePtr->name;
  303.     }
  304.     } else if ((c == 't') && (strcmp(argv[1], "types") == 0)) {
  305.     if (argc != 2) {
  306.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  307.             " types\"", (char *) NULL);
  308.         return TCL_ERROR;
  309.     }
  310.     for (typePtr = imageTypeList; typePtr != NULL;
  311.         typePtr = typePtr->nextPtr) {
  312.         Tcl_AppendElement(interp, typePtr->name);
  313.     }
  314.     } else if ((c == 'w') && (strncmp(argv[1], "width", length) == 0)) {
  315.     if (argc != 3) {
  316.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  317.             " width name\"", (char *) NULL);
  318.         return TCL_ERROR;
  319.     }
  320.     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, argv[2]);
  321.     if (hPtr == NULL) {
  322.         Tcl_AppendResult(interp, "image \"", argv[2],
  323.             "\" doesn't exist", (char *) NULL);
  324.         return TCL_ERROR;
  325.     }
  326.     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
  327.     sprintf(interp->result, "%d", masterPtr->width);
  328.     } else {
  329.     Tcl_AppendResult(interp, "bad option \"", argv[1],
  330.         "\": must be create, delete, height, names, type, types,",
  331.         " or width", (char *) NULL);
  332.     return TCL_ERROR;
  333.     }
  334.     return TCL_OK;
  335. }
  336.  
  337. /*
  338.  *----------------------------------------------------------------------
  339.  *
  340.  * Tk_ImageChanged --
  341.  *
  342.  *    This procedure is called by an image manager whenever something
  343.  *    has happened that requires the image to be redrawn (some of its
  344.  *    pixels have changed, or its size has changed).
  345.  *
  346.  * Results:
  347.  *    None.
  348.  *
  349.  * Side effects:
  350.  *    Any widgets that display the image are notified so that they
  351.  *    can redisplay themselves as appropriate.
  352.  *
  353.  *----------------------------------------------------------------------
  354.  */
  355.  
  356. void
  357. Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth,
  358.     imageHeight)
  359.     Tk_ImageMaster imageMaster;    /* Image that needs redisplay. */
  360.     int x, y;            /* Coordinates of upper-left pixel of
  361.                  * region of image that needs to be
  362.                  * redrawn. */
  363.     int width, height;        /* Dimensions (in pixels) of region of
  364.                  * image to redraw.  If either dimension
  365.                  * is zero then the image doesn't need to
  366.                  * be redrawn (perhaps all that happened is
  367.                  * that its size changed). */
  368.     int imageWidth, imageHeight;/* New dimensions of image. */
  369. {
  370.     ImageMaster *masterPtr = (ImageMaster *) imageMaster;
  371.     Image *imagePtr;
  372.  
  373.     masterPtr->width = imageWidth;
  374.     masterPtr->height = imageHeight;
  375.     for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
  376.         imagePtr = imagePtr->nextPtr) {
  377.     (*imagePtr->changeProc)(imagePtr->widgetClientData, x, y,
  378.         width, height, imageWidth, imageHeight);
  379.     }
  380. }
  381.  
  382. /*
  383.  *----------------------------------------------------------------------
  384.  *
  385.  * Tk_NameOfImage --
  386.  *
  387.  *    Given a token for an image master, this procedure returns
  388.  *    the name of the image.
  389.  *
  390.  * Results:
  391.  *    The return value is the string name for imageMaster.
  392.  *
  393.  * Side effects:
  394.  *    None.
  395.  *
  396.  *----------------------------------------------------------------------
  397.  */
  398.  
  399. char *
  400. Tk_NameOfImage(imageMaster)
  401.     Tk_ImageMaster imageMaster;        /* Token for image. */
  402. {
  403.     ImageMaster *masterPtr = (ImageMaster *) imageMaster;
  404.  
  405.     return Tcl_GetHashKey(masterPtr->tablePtr, masterPtr->hPtr);
  406. }
  407.  
  408. /*
  409.  *----------------------------------------------------------------------
  410.  *
  411.  * Tk_GetImage --
  412.  *
  413.  *    This procedure is invoked by a widget when it wants to use
  414.  *    a particular image in a particular window.
  415.  *
  416.  * Results:
  417.  *    The return value is a token for the image.  If there is no image
  418.  *    by the given name, then NULL is returned and an error message is
  419.  *    left in interp->result.
  420.  *
  421.  * Side effects:
  422.  *    Tk records the fact that the widget is using the image, and
  423.  *    it will invoke changeProc later if the widget needs redisplay
  424.  *    (i.e. its size changes or some of its pixels change).  The
  425.  *    caller must eventually invoke Tk_FreeImage when it no longer
  426.  *    needs the image.
  427.  *
  428.  *----------------------------------------------------------------------
  429.  */
  430.  
  431. Tk_Image
  432. Tk_GetImage(interp, tkwin, name, changeProc, clientData)
  433.     Tcl_Interp *interp;        /* Place to leave error message if image
  434.                  * can't be found. */
  435.     Tk_Window tkwin;        /* Token for window in which image will
  436.                  * be used. */
  437.     char *name;            /* Name of desired image. */
  438.     Tk_ImageChangedProc *changeProc;
  439.                 /* Procedure to invoke when redisplay is
  440.                  * needed because image's pixels or size
  441.                  * changed. */
  442.     ClientData clientData;    /* One-word argument to pass to damageProc. */
  443. {
  444.     Tcl_HashEntry *hPtr;
  445.     ImageMaster *masterPtr;
  446.     Image *imagePtr;
  447.  
  448.     hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->imageTable, name);
  449.     if (hPtr == NULL) {
  450.     goto noSuchImage;
  451.     }
  452.     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
  453.     if (masterPtr->typePtr == NULL) {
  454.     goto noSuchImage;
  455.     }
  456.     imagePtr = (Image *) ckalloc(sizeof(Image));
  457.     imagePtr->tkwin = tkwin;
  458.     imagePtr->display = Tk_Display(tkwin);
  459.     imagePtr->masterPtr = masterPtr;
  460.     imagePtr->instanceData =
  461.         (*masterPtr->typePtr->getProc)(tkwin, masterPtr->masterData);
  462.     imagePtr->changeProc = changeProc;
  463.     imagePtr->widgetClientData = clientData;
  464.     imagePtr->nextPtr = masterPtr->instancePtr;
  465.     masterPtr->instancePtr = imagePtr;
  466.     return (Tk_Image) imagePtr;
  467.  
  468.     noSuchImage:
  469.     Tcl_AppendResult(interp, "image \"", name, "\" doesn't exist",
  470.         (char *) NULL);
  471.     return NULL;
  472. }
  473.  
  474. /*
  475.  *----------------------------------------------------------------------
  476.  *
  477.  * Tk_FreeImage --
  478.  *
  479.  *    This procedure is invoked by a widget when it no longer needs
  480.  *    an image acquired by a previous call to Tk_GetImage.  For each
  481.  *    call to Tk_GetImage there must be exactly one call to Tk_FreeImage.
  482.  *
  483.  * Results:
  484.  *    None.
  485.  *
  486.  * Side effects:
  487.  *    The association between the image and the widget is removed.
  488.  *
  489.  *----------------------------------------------------------------------
  490.  */
  491.  
  492. void
  493. Tk_FreeImage(image)
  494.     Tk_Image image;        /* Token for image that is no longer
  495.                  * needed by a widget. */
  496. {
  497.     Image *imagePtr = (Image *) image;
  498.     ImageMaster *masterPtr = imagePtr->masterPtr;
  499.     Image *prevPtr;
  500.  
  501.     /*
  502.      * Clean up the particular instance.
  503.      */
  504.  
  505.     if (masterPtr->typePtr != NULL) {
  506.     (*masterPtr->typePtr->freeProc)(imagePtr->instanceData,
  507.         imagePtr->display);
  508.     }
  509.     prevPtr = masterPtr->instancePtr;
  510.     if (prevPtr == imagePtr) {
  511.     masterPtr->instancePtr = imagePtr->nextPtr;
  512.     } else {
  513.     while (prevPtr->nextPtr != imagePtr) {
  514.         prevPtr = prevPtr->nextPtr;
  515.     }
  516.     prevPtr->nextPtr = imagePtr->nextPtr;
  517.     }
  518.     ckfree((char *) imagePtr);
  519.  
  520.     /* 
  521.      * If there are no more instances left for the master, and if the
  522.      * master image has been deleted, then delete the master too.
  523.      */
  524.  
  525.     if ((masterPtr->typePtr == NULL) && (masterPtr->instancePtr == NULL)) {
  526.     Tcl_DeleteHashEntry(masterPtr->hPtr);
  527.     ckfree((char *) masterPtr);
  528.     }
  529. }
  530.  
  531. /*
  532.  *----------------------------------------------------------------------
  533.  *
  534.  * Tk_RedrawImage --
  535.  *
  536.  *    This procedure is called by widgets that contain images in order
  537.  *    to redisplay an image on the screen or an off-screen pixmap.
  538.  *
  539.  * Results:
  540.  *    None.
  541.  *
  542.  * Side effects:
  543.  *    The image's manager is notified, and it redraws the desired
  544.  *    portion of the image before returning.
  545.  *
  546.  *----------------------------------------------------------------------
  547.  */
  548.  
  549. void
  550. Tk_RedrawImage(image, imageX, imageY, width, height, drawable,
  551.     drawableX, drawableY)
  552.     Tk_Image image;        /* Token for image to redisplay. */
  553.     int imageX, imageY;        /* Upper-left pixel of region in image that
  554.                  * needs to be redisplayed. */
  555.     int width, height;        /* Dimensions of region to redraw. */
  556.     Drawable drawable;        /* Drawable in which to display image
  557.                  * (window or pixmap).  If this is a pixmap,
  558.                  * it must have the same depth as the window
  559.                  * used in the Tk_GetImage call for the
  560.                  * image. */
  561.     int drawableX, drawableY;    /* Coordinates in drawable that correspond
  562.                  * to imageX and imageY. */
  563. {
  564.     Image *imagePtr = (Image *) image;
  565.  
  566.     if (imagePtr->masterPtr->typePtr == NULL) {
  567.     /*
  568.      * No master for image, so nothing to display.
  569.      */
  570.  
  571.     return;
  572.     }
  573.  
  574.     /*
  575.      * Clip the redraw area to the area of the image.
  576.      */
  577.  
  578.     if (imageX < 0) {
  579.     width += imageX;
  580.     drawableX -= imageX;
  581.     imageX = 0;
  582.     }
  583.     if (imageY < 0) {
  584.     height += imageY;
  585.     drawableY -= imageY;
  586.     imageY = 0;
  587.     }
  588.     if ((imageX + width) > imagePtr->masterPtr->width) {
  589.     width = imagePtr->masterPtr->width - imageX;
  590.     }
  591.     if ((imageY + height) > imagePtr->masterPtr->height) {
  592.     height = imagePtr->masterPtr->height - imageY;
  593.     }
  594.     (*imagePtr->masterPtr->typePtr->displayProc)(
  595.         imagePtr->instanceData, imagePtr->display, drawable,
  596.         imageX, imageY, width, height, drawableX, drawableY);
  597. }
  598.  
  599. /*
  600.  *----------------------------------------------------------------------
  601.  *
  602.  * Tk_SizeOfImage --
  603.  *
  604.  *    This procedure returns the current dimensions of an image.
  605.  *
  606.  * Results:
  607.  *    The width and height of the image are returned in *widthPtr
  608.  *    and *heightPtr.
  609.  *
  610.  * Side effects:
  611.  *    None.
  612.  *
  613.  *----------------------------------------------------------------------
  614.  */
  615.  
  616. void
  617. Tk_SizeOfImage(image, widthPtr, heightPtr)
  618.     Tk_Image image;        /* Token for image whose size is wanted. */
  619.     int *widthPtr;        /* Return width of image here. */
  620.     int *heightPtr;        /* Return height of image here. */
  621. {
  622.     Image *imagePtr = (Image *) image;
  623.  
  624.     *widthPtr = imagePtr->masterPtr->width;
  625.     *heightPtr = imagePtr->masterPtr->height;
  626. }
  627.  
  628. /*
  629.  *----------------------------------------------------------------------
  630.  *
  631.  * Tk_DeleteImage --
  632.  *
  633.  *    Given the name of an image, this procedure destroys the
  634.  *    image.
  635.  *
  636.  * Results:
  637.  *    None.
  638.  *
  639.  * Side effects:
  640.  *    The image is destroyed; existing instances will display as
  641.  *    blank areas.  If no such image exists then the procedure does
  642.  *    nothing.
  643.  *
  644.  *----------------------------------------------------------------------
  645.  */
  646.  
  647. void
  648. Tk_DeleteImage(interp, name)
  649.     Tcl_Interp *interp;        /* Interpreter in which the image was
  650.                  * created. */
  651.     char *name;            /* Name of image. */
  652. {
  653.     Tcl_HashEntry *hPtr;
  654.     TkWindow *winPtr;
  655.  
  656.     winPtr = (TkWindow *) Tk_MainWindow(interp);
  657.     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
  658.     if (hPtr == NULL) {
  659.     return;
  660.     }
  661.     DeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr));
  662. }
  663.  
  664. /*
  665.  *----------------------------------------------------------------------
  666.  *
  667.  * DeleteImage --
  668.  *
  669.  *    This procedure is responsible for deleting an image.
  670.  *
  671.  * Results:
  672.  *    None.
  673.  *
  674.  * Side effects:
  675.  *    The connection is dropped between instances of this image and
  676.  *    an image master.  Image instances will redisplay themselves
  677.  *    as empty areas, but existing instances will not be deleted.
  678.  *
  679.  *----------------------------------------------------------------------
  680.  */
  681.  
  682. static void
  683. DeleteImage(masterPtr)
  684.     ImageMaster *masterPtr;    /* Pointer to main data structure for image. */
  685. {
  686.     Image *imagePtr;
  687.     Tk_ImageType *typePtr;
  688.  
  689.     typePtr = masterPtr->typePtr;
  690.     masterPtr->typePtr = NULL;
  691.     if (typePtr != NULL) {
  692.     for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
  693.         imagePtr = imagePtr->nextPtr) {
  694.        (*typePtr->freeProc)(imagePtr->instanceData,
  695.            imagePtr->display);
  696.        (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0,
  697.             masterPtr->width, masterPtr->height, masterPtr->width,
  698.             masterPtr->height);
  699.     }
  700.     (*typePtr->deleteProc)(masterPtr->masterData);
  701.     }
  702.     if (masterPtr->instancePtr == NULL) {
  703.     Tcl_DeleteHashEntry(masterPtr->hPtr);
  704.     ckfree((char *) masterPtr);
  705.     }
  706. }
  707.  
  708. /*
  709.  *----------------------------------------------------------------------
  710.  *
  711.  * TkDeleteAllImages --
  712.  *
  713.  *    This procedure is called when an application is deleted.  It
  714.  *    calls back all of the managers for all images so that they
  715.  *    can cleanup, then it deletes all of Tk's internal information
  716.  *    about images.
  717.  *
  718.  * Results:
  719.  *    None.
  720.  *
  721.  * Side effects:
  722.  *    All information for all images gets deleted.
  723.  *
  724.  *----------------------------------------------------------------------
  725.  */
  726.  
  727. void
  728. TkDeleteAllImages(mainPtr)
  729.     TkMainInfo *mainPtr;    /* Structure describing application that is
  730.                  * going away. */
  731. {
  732.     Tcl_HashSearch search;
  733.     Tcl_HashEntry *hPtr;
  734.     ImageMaster *masterPtr;
  735.  
  736.     for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search);
  737.         hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
  738.     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
  739.     DeleteImage(masterPtr);
  740.     }
  741.     Tcl_DeleteHashTable(&mainPtr->imageTable);
  742. }
  743.  
  744. /*
  745.  *----------------------------------------------------------------------
  746.  *
  747.  * Tk_GetImageMasterData --
  748.  *
  749.  *    Given the name of an image, this procedure returns the type
  750.  *    of the image and the clientData associated with its master.
  751.  *
  752.  * Results:
  753.  *    If there is no image by the given name, then NULL is returned
  754.  *    and a NULL value is stored at *typePtrPtr.  Otherwise the return
  755.  *    value is the clientData returned by the createProc when the
  756.  *    image was created and a pointer to the type structure for the
  757.  *    image is stored at *typePtrPtr.
  758.  *
  759.  * Side effects:
  760.  *    None.
  761.  *
  762.  *----------------------------------------------------------------------
  763.  */
  764.  
  765. ClientData
  766. Tk_GetImageMasterData(interp, name, typePtrPtr)
  767.     Tcl_Interp *interp;        /* Interpreter in which the image was
  768.                  * created. */
  769.     char *name;            /* Name of image. */
  770.     Tk_ImageType **typePtrPtr;    /* Points to location to fill in with
  771.                  * pointer to type information for image. */
  772. {
  773.     Tcl_HashEntry *hPtr;
  774.     TkWindow *winPtr;
  775.     ImageMaster *masterPtr;
  776.  
  777.     winPtr = (TkWindow *) Tk_MainWindow(interp);
  778.     hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
  779.     if (hPtr == NULL) {
  780.     *typePtrPtr = NULL;
  781.     return NULL;
  782.     }
  783.     masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
  784.     *typePtrPtr = masterPtr->typePtr;
  785.     return masterPtr->masterData;
  786. }
  787.